package com.chehejia.devmng.platform.java8.java_stream.demo;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

/**
 *  * @Description: 使用 stream 替换传统他for 循环
 *  * @author: 王永坤
 *  * @Date: 2018/12/27 17:12
 *  
 */
@Slf4j
public class Test1 {


    @Test
    public void  run1(){
// 查找张三的男人，for是这样的，
        List<Man> men = initData();
        List<Man> zsMan =new ArrayList<>();
        for (Man man : men) {
            if ("张三".equals(man.getName())){
                zsMan.add(man);
            }
        }
        // 这个 filter 相当也数据库中 where
        List<Man> manList = men.stream().filter(m -> "张三".equals(m.getName())).collect(toList());
        System.out.println(zsMan.size()+"--"+manList.size());
        //2，继续，查找id为007的男人，id唯一，for是这样的
        Man man = men.stream().filter(m -> "007".equals(m.getAge())).findFirst().orElse(null);
        // 如果不存就是返回null
        System.out.println(man);
        //3，继续，获取名字叫张三（因有同名）的所有银行卡
        //
        List<Card> cards = men.stream().filter(m -> "张三".equals(m.getName())).flatMap(m -> m.getCardList().stream()).collect(toList());
        System.out.println(cards.size());
    }
    @Test
    public void testMapAndFlatMap() {
        List<String> words = new ArrayList<String>();
        words.add("hello");
        words.add("word");

        //将words数组中的元素再按照字符拆分，然后字符去重，最终达到["h", "e", "l", "o", "w", "r", "d"]
        //如果使用map，是达不到直接转化成List<String>的结果
        List<String> stringList = words.stream()
                .flatMap(word -> Arrays.stream(word.split("")))
                .distinct()
                .collect(toList());
        stringList.forEach(e -> System.out.println(e));
    }


    /**
     * map 映射使用 ，它会接受一个函数作为参数。这个函数会被应用到每个元素上，并将其映射成一个新的元素
     * 给定一个数字列表，如何返回一个由每个数的平方构成的列表呢？例如，给定[1, 2, 3, 4,5]，应该返回[1, 4, 9, 16, 25]。
     */
    @Test
    public void  test1(){
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        List<Integer> collect = integers.stream().map(n -> n * n).collect(toList());
        collect.forEach(System.out::println);
    }

    /**
     * 给定列表[1, 2, 3]和列表[3, 4]，应该返回[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]
     * @return
     */
    @Test
    public void  test2(){
        List<Integer> integers1 = Arrays.asList(1, 2, 3);
        List<Integer> integers2 = Arrays.asList(3,4);
        /**
         * int[]num;//声明了一个int类型的数组,但并未为其分配内存空间.
         * num=new int[3];//为num数组分配了三个元素的空间.
         */
        int[] ints = {1, 3};
        /**
         * 你可以使用两个map来迭代这两个列表，并生成数对。但这样会返回一个Stream-
         * <Stream<Integer[]>>。你需要让生成的流扁平化，以得到一个Stream<Integer[]>。这
         * 正是flatMap所做的：
         */
        List<int[]> collect = integers1.stream().flatMap(i ->
                integers2.stream().map(j -> new int[]{i, j})).collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 扩展 test2 的问题，只返回总和能被3整除的数对呢
     */
    @Test
    public void  test3(){
        List<Integer> integers1 = Arrays.asList(1, 2, 3);
        List<Integer> integers2 = Arrays.asList(3,4);
        List<int[]> collect = integers1.stream().flatMap(i ->
                integers2.stream()
                        .filter(j -> (i + j) % 3 == 0)
                        .map(j -> new int[]{i, j})
        ).collect(toList());

        collect.forEach(System.out::println);
    }















    private List<Man> initData() {
        List<Man> mans = new ArrayList<>();
        mans.add(new Man("001", "张三", Arrays.asList(new Card("工商银行", "9558800001"), new Card("工商银行", "9558800002"), new Card("建设银行", "6227001234"))));
        mans.add(new Man("002", "李四", Arrays.asList(new Card("招商银行", "6225800002"), new Card("建设银行", "6227035248"))));
        mans.add(new Man("003", "王五", Arrays.asList(new Card("建设银行", "6227056547"), new Card("中国银行", "6013832547"), new Card("民生银行", "4074058542"))));
        mans.add(new Man("004", "赵六", Arrays.asList(new Card("工商银行", "9558832458"), new Card("工商银行", "9558832547"), new Card("建设银行", "6227032578"))));
        mans.add(new Man("005", "孙七", Arrays.asList(new Card("中国银行", "6013825847"), new Card("农业银行", "6228836547"), new Card("招商银行", "6225014582"))));
        mans.add(new Man("006", "张三", Arrays.asList(new Card("工商银行", "9558832587"), new Card("交通银行", "6222814578"), new Card("工商银行", "9558865427"))));
        // 查找张三的男人，for是这样的，
        return mans;
    }
}
